<?php
/**
 * Administration panel
 * @package Admin
 * @author Urban Soban
 * @version 0.1
 * @copyright Urban Soban
 * @link http://masterplan.sobanu.net
 */

class AdminController extends ApplicationController {
	protected $AppName = "admin";
	protected $HeadTags = array("<script type=\"text/javascript\" src=\"{\$env.url}lib/admin/admin.js\"></script>",
								"<link rel=\"stylesheet\" type=\"text/css\" href=\"{\$env.url}lib/admin/views/admin.css\" />");
	protected $UseApps = array(array("name" => "account"),
								array("name" => "smarty", "method" => "getSmarty"),
							    array("name" => "redirector"));

	/**
	 * Functions, registered by modules
	 * @var array
	 */
	private $RegisteredFunctions = array();

	/**
	 * List of applications with configuration.php file
	 * @var array
	 */
	private $Applications = array();

	/**
	 * HTTPRequest object
	 *
	 * @var HTTPRequest
	 */
	private $HTTP;

	/**
	 * Tells application if request has been made using ajax parameter
	 *
	 * @var bool
	 */
	private $IsAjax = false;

	function __construct(){
		parent::__construct();

		/* Check if user can access application, otherwise redirect to login page */
		$Account = $this->UseApps["account"];
		if(!$Account->canAccess($this->AppName)){
			$Redirector = $this->UseApps["redirector"];
			$_SESSION["fms_redirect"] = Core::$FMSConfig->getValue("environment", "url")."admin/";
			$Redirector->redirect(Core::$FMSConfig->getValue("environment", "url")."account/login/");
		}
	}

	function init(){
		$smarty = $this->UseApps["smarty"];
		$this->Applications = $this->scanFolders();		// Scan folders for configuration files

		$URLPosition = SystemRegistry::getInstance()->get("url_position");
		$this->HTTP = new HTTPRequest();

		$CalledByURL = $this->HTTP->get($URLPosition-1);

		if($CalledByURL != "admin"){
			return false;
		}

		$this->IsAjax = ($this->HTTP->get($URLPosition-2) == false) ? false : true;

		// we assign varible to tell smarty admin panel is on, so in tha designer can remove part of design, let's say flash header
		$smarty->assign("AdminPanel", true);

		$URL_Action = $this->HTTP->get($URLPosition);

		switch ($URL_Action){
			case "configure":
				// get app name
				$AppName = $this->HTTP->get($URLPosition+1);

				// if application is not configurable, display message
				if(!in_array($AppName, $this->Applications)){
					$this->ViewFile = "message.tpl";
					return "Application doesn't exist.";
				}

				$ConfigurationResult = $this->runConfiguration($AppName);

				// display application's configuration options
				if($ConfigurationResult === false){
					$this->ViewFile = "configuration.tpl";
					$smarty->assign("admin_application_methods", $this->RegisteredFunctions[$AppName]);
					$smarty->assign("admin_chosen_app", $AppName);
					return;
				}
				elseif ($this->IsAjax === true){
					if(is_file($ConfigurationResult)){
						return $smarty->fetch("file:".$ConfigurationResult);
					}

					return $ConfigurationResult;
				}
				else {
					$this->ViewFile = "configure_app.tpl";
					$smarty->assign("admin_configure_app_output", $ConfigurationResult);
					$smarty->assign("admin_chosen_app", $AppName);
					return;
				}

			break;
			default:
				$this->ViewFile = "default.tpl";
				$smarty->assign("admin_application_list", $this->Applications);
			break;
		}

		return;
	}

	/**
	 * Scans all application directories for configuration.php file
	 * @return array List of applications with config file
	 */
	function scanFolders(){
		$Path = dirname(__FILE__)."/../";
		$ScanFolders = scandir($Path);

		$Folders = array();

		foreach ($ScanFolders as $Folder){
			if($Folder != "." && $Folder != ".." && $Folder != "smarty" && $Folder != "admin"){
				if(file_exists($Path.$Folder."/configuration.php")){
					$Folders[] = $Folder;
				}
			}
		}
		sort($Folders);

		return $Folders;
	}

	/**
	 * Registers function
	 *
	 * @param string $application
	 * @param string $request_part
	 * @param string $run_method
	 * @param string $display_label
	 */
	function register($application, $request_part, $run_method, $display_label = null){
		$this->RegisteredFunctions[$application][$request_part]["run"] = $run_method;
		$this->RegisteredFunctions[$application][$request_part]["label"] = $display_label;
	}

	/**
	 * Runs application configuration
	 *
	 * @param string $app_name
	 * @return string
	 */
	function runConfiguration($app_name){
		// Prepare configuration environment, file and class
		$ConfigurationFilePath = dirname(__FILE__)."/../".strtolower($app_name)."/configuration.php";
		require_once($ConfigurationFilePath);

		$ConfigClassName = ucfirst($app_name)."Configuration";

		if(!class_exists($ConfigClassName)){
			throw new FMSException("$ConfigClassName not found.");
		}

		$ConfigObject = new $ConfigClassName($this);
		$ConfigObject->registerMethods($this);

		// Check called config function
		$URLPosition = SystemRegistry::getInstance()->get("url_position");
		$URL_Method = $this->HTTP->get($URLPosition+2);

		if(trim($URL_Method) == null){
			return false;
		}

		$AppMethods = $this->RegisteredFunctions[$app_name];

		if(!isset($AppMethods[$URL_Method])){
			throw new FMSException("$URL_Method doesn't exist.");
		}
		else {
			$ConfigMethod = $AppMethods[$URL_Method]["run"];
		}
		// Assign results
		$smarty = $this->UseApps["smarty"];
		$smarty->assign("admin_chosen_method", $ConfigMethod);

		$ConfigResult = $ConfigObject->$ConfigMethod();

		if(is_bool($ConfigResult) && !is_string($ConfigResult)){
			$ViewFile = $ConfigObject->getView();

			if($ViewFile != null){
				$path = dirname(__FILE__)."/../".strtolower($app_name)."/views/".$ViewFile;
				$ConfigResult = "{include file='file:$path'}";

				if($this->IsAjax === true){
					$ConfigResult = $path;
				}
			}
		}

		return $ConfigResult;
	}
}

?>